package Thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 有A,B,C三个线程，A线程输出"a",B线程输出"b",C线程输出"c",请写一段代码实现同时启动三个线程,按顺序输出“abc”，循环5次。
 */
public class PrintABC {

    Lock lock=new ReentrantLock();
    volatile int  flags=1;
    Condition  conditionA= lock.newCondition();
    Condition  conditionB= lock.newCondition();
    Condition  conditionC= lock.newCondition();

    public static void main(String[] args) {

        PrintABC  printABC=new PrintABC();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                printABC.printA();
            }
        },"线程A").start();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                printABC.printB();
            }
        },"线程B").start();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                printABC.printC();
            }
        },"线程C").start();
    }


    public void printA(){
        try {
            lock.lock();
            while (flags!=1){
                conditionA.await();
            }
            System.out.println(Thread.currentThread().getName());
            conditionB.signal();
            flags=2;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void printB(){
        try {
            lock.lock();
            while (flags!=2){
                conditionB.await();
            }
            System.out.println(Thread.currentThread().getName());
            conditionC.signal();
            flags=3;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void printC(){
        try {
            lock.lock();
            while (flags!=3){
                conditionC.await();
            }
            System.out.println(Thread.currentThread().getName());
            conditionA.signal();
            flags=1;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
